home *** CD-ROM | disk | FTP | other *** search
/ Top 101 Multimedia Shareware '93 / Top 101 Multimedia Shareware 1993.iso / movingvg / pyro.c < prev    next >
Text File  |  1987-10-25  |  12KB  |  197 lines

  1. char c[]="PYRO - A Simulated Pyrotechnics display  20/10/87  (c) 1987 K.G. Shields",
  2.     inkey,txt[]="THE END";
  3. #include <stdlib.h>
  4. #include <dos.h>
  5. #include <math.h>
  6. #define NI 6 /*Number of items*/
  7. #define NP 60 /*Number of points per item*/
  8. #define TP 400 /*Total number of points*/
  9. union REGS inr,outr;
  10. int xl[NI],xh[NI],yl[NI],yh[NI],vell[NI],velh[NI],angl[NI],angh[NI],alivel[NI],
  11.     aliveh[NI],coll[NI],colh[NI],sizel[NI],sizeh[NI],fadev[NI],item_alive[NI],
  12.     devicetype[NI],wait[NI],master[NI],g[TP],x[TP],y[TP],xvel[TP],yvel[TP],
  13.     alive[TP],col[TP],size[TP],fade[TP],itemno[TP],next[TP],state[TP],im,jm,km,
  14.     xmin,xmax,ymin,ymax,xend,yend,newpt,endpt,ci,num_active,num_dormant,freep,
  15.     mastercol,sh=5,spurt=1,flare=2,burst=3,rocket=4,roman=5,sep=180,scan=179,
  16.     gv=2,slowdown=80,statev=0,burstlife=10,noise=0;
  17. float sina[361],cosa[361];
  18. void terminate();
  19. void setrange(int *d1,int *d2,int s1,int s2) /*Store limits information*/
  20. {   if (s1<=s2) {*d1=s1;    *d2=s2;} else {*d1=s2;    *d2=s1;}   } /*End setrange*/
  21. void limits(int it,int lxl,int lxh,int lyl,int lyh,int lvell,int lvelh,int langl,int langh,int lalivel,int laliveh,
  22. int lcoll,int lcolh,int lsizel,int lsizeh,int lfade) /*Set limits for point generation for item it*/
  23. {   setrange(&xl[it],&xh[it],lxl<<sh,lxh<<sh);
  24.     setrange(&yl[it],&yh[it],lyl<<sh,lyh<<sh);
  25.     setrange(&vell[it],&velh[it],lvell<<sh,lvelh<<sh);
  26.     setrange(&angl[it],&angh[it],langl,langh);
  27.     setrange(&alivel[it],&aliveh[it],lalivel,laliveh);
  28.     setrange(&coll[it],&colh[it],lcoll,lcolh);
  29.     setrange(&sizel[it],&sizeh[it],lsizel,lsizeh);
  30.     fadev[it]=lfade;} /*End limits*/
  31. int rnd(int low,int high) /*Returns a value between low and high (inclusive)*/
  32. {   return low+(((long)rand()*(high-low+1))>>15);} /*End rnd*/
  33. void show(int x,int y,int col,int size) /*Show (or remove) point x,y if it is visible*/
  34. {   int i,x1,x2,dummy,address,lbit,rbit;
  35.     if (y>=ymin) if (y<=ymax) if (x>=xmin) if (x<=xmax) {
  36.         outportb(0x3ce,3);    outportb(0x3cf,0x18);/*Select Xor operation*/
  37.         for (i=-(size-1); i<=size-1; i++) {
  38.             x1=(x>>sh)-(size-1-abs(i));    x2=(x>>sh)+(size-1-abs(i));
  39.             while (x1<=x2) {
  40.                 lbit=x1 & 7;    rbit=(x2>=(x1 | 7))? 7 : lbit+x2-x1;
  41.                 outportb(0x3ce,8);
  42.                 outportb(0x3cf,(unsigned char)(0xff<<(7-rbit+lbit))>>lbit);/*Set mask*/
  43.                 dummy=peekb(0xa000,address=((y>>sh)+i)*80+(x1>>3));/*Load latches*/
  44.                 outportb(0x3c4,2);    outportb(0x3c5,col);/*Select bit planes*/
  45.                 pokeb(0xa000,address,0xff);/*Set selected bits to 1*/
  46.                 x1=x1+rbit-lbit+1;}   }
  47.     outportb(0x3ce,3);    outportb(0x3cf,0);/*Cancel Xor*/
  48.     outportb(0x3ce,8);    outportb(0x3cf,0xff);/*No mask*/
  49.     outportb(0x3c4,2);    outportb(0x3c5,0xff);/*Enable all bit planes*/}   } /*End limits*/
  50. void release(int pt) /*Release point pt*/
  51. {   alive[pt]=abs(alive[pt]);    scan=max(scan,pt);} /*End release*/
  52. void create(int it,int *pt) /*Create a point for item it*/
  53. {   int vel,angle;
  54.     if (freep>=0) {*pt=freep;    freep=next[*pt];
  55.     } else {for (*pt=sep;(*pt<TP) && (alive[*pt]!=0);(*pt)++); *pt=min(*pt,TP-1);}
  56.     itemno[*pt]=it;    g[*pt]=gv;       fade[*pt]=fadev[it];    state[*pt]=statev;
  57.     x[*pt]=rnd(xl[it],xh[it]);          y[*pt]=rnd(yl[it],yh[it]);
  58.     vel=rnd(vell[it],velh[it]);         angle=rnd(angl[it],angh[it]);
  59.     xvel[*pt]=vel*sina[180+angle];      yvel[*pt]=-(vel*cosa[180+angle]);
  60.     col[*pt]=rnd(coll[it],colh[it]);    size[*pt]=rnd(sizel[it],sizeh[it]);
  61.     if ((alive[*pt]=rnd(alivel[it],aliveh[it]))>0) release(*pt);} /*End create*/
  62. void move_points() /*Move all active points through 1 step*/
  63. {   int i,j;
  64.     num_active=0;    num_dormant=0;
  65.     for (j=0;j<=scan;j++)
  66.         if (alive[j]<=0) {
  67.             if (j<sep) for (i=1;i<=slowdown;i++);    if (alive[j]<0) num_dormant++;
  68.         } else {
  69.             if (noise>0) if (rand()<noise) outportb(0x61,3);
  70.             if (state[j]>0) show(x[j],y[j],col[j],size[j]);
  71.             else if (state[j]==0) state[j]=1;
  72.             num_active++;    alive[j]--;    yvel[j]+=g[j];    x[j]+=xvel[j];
  73.             if ((y[j]+=yvel[j])>ymax) {y[j]-=yvel[j]; xvel[j]=0;}
  74.             if (alive[j]==0)
  75.                 if (g[j]==0) {
  76.                     g[j]=gv;    alive[j]=10;
  77.                 } else if (size[j]>1) {
  78.                     size[j]--;    alive[j]=fade[j];
  79.                 } else {
  80.                     col[j]=0;    if (j<sep) {next[j]=freep;    freep=j;}   }
  81.         show(x[j],y[j],col[j],size[j]);    outportb(0x61,0);}
  82.     while ((scan>=sep) && (alive[scan]<=0)) scan--;
  83.     if ((noise=abs(noise))>0) noise-=300;} /*End move_points*/
  84. void process(int t,int waiting) /*Process currently set devices for t intervals*/
  85. {   int it,i,timer;
  86.     for (timer=1;timer<=t;timer++) {
  87.         for (it=0;it<NI;it++) {
  88.             if (item_alive[it]>0) item_alive[it]--; else devicetype[it]=0;
  89.             switch(devicetype[it]) {
  90.             /*SPURT*/ case 1:   if (wait[it]>130) create(it,&newpt);
  91.                 else if (wait[it]==0) {
  92.                     setrange(&coll[it],&colh[it],rnd(9,15),rnd(9,15));
  93.                     wait[it]=NP+130;}    break;
  94.             /*FLARE*/ case 2:   create(it,&newpt);
  95.                 if (wait[it]==0) {
  96.                     if (++coll[it]>=14) coll[it]=9;
  97.                     colh[it]=coll[it]+1;    wait[it]=50;}    break;
  98.             /*BURST*/ case 3:   if (wait[it]>0) create(it,&master[it]);
  99.                 else if (wait[it]==0) {
  100.                     for (i=0;i<TP;i++) if ((alive[i]<0) && (itemno[i]==it)) release(i);
  101.                     noise=-3000;}    break;
  102.             /*ROCKET*/ case 4:  if (wait[it]==0) {release(master[it]);
  103.                     item_alive[it]=alive[master[it]]+fade[master[it]]*(size[master[it]]-1);}
  104.                 if (alive[master[it]]>0) {
  105.                     create(it,&newpt);    x[newpt]=x[master[it]]+rnd(-64,64);
  106.                     y[newpt]=y[master[it]]+rnd(-64,64);    release(newpt);}    break;
  107.             /*ROMAN*/ case 5:   if ((wait[it]<=9) && (wait[it]>0)) {create(it,&newpt);
  108.                     x[newpt]=x[master[it]]+(3<<sh)*sina[180+(360*(wait[it]-5)/9)];
  109.                     y[newpt]=y[master[it]]-(3<<sh)*cosa[180+(360*(wait[it]-5)/9)];
  110.                     xvel[newpt]=xvel[master[it]];      yvel[newpt]=yvel[master[it]];
  111.                     alive[newpt]=alive[master[it]];    col[newpt]=col[master[it]];
  112.                 } else if (wait[it]==0) {
  113.                     limits(it,0,0,0,0,0,0,0,0,-10,-5,col[master[it]],col[master[it]],1,1,0);
  114.                     for (i=0;i<TP;i++) if ((alive[i]<0) && (itemno[i]==it)) release(i);
  115.                     item_alive[it]=alive[master[it]]+fade[master[it]]*(size[master[it]]-1);}
  116.                     if (alive[master[it]]>0) {create(it,&newpt);
  117.                         x[newpt]=x[master[it]]+rnd(-256,256);    y[newpt]=y[master[it]]+rnd(-64,64);
  118.                         release(newpt);}   } /*End switch*/
  119.             if ((wait[it]>-1) && (it!=waiting)) wait[it]--;}
  120.         if (kbhit()) terminate();
  121.         move_points();}   } /*End process*/
  122. void terminate() /*Terminate display*/
  123. {   int i,j,k,l;
  124.     if ((inkey=kbhit()? getch(): 0)==27) exit(0);
  125.     for (j=1;(j<=800) && (num_active+num_dormant>0);j++) process(1,-1);
  126.     gv=0;    statev=0;    for (j=0;j<28000;j++) pokeb(0xa000,j,0);
  127.     for (i=0;i<=6;i++) {
  128.         if (txt[i]!=' ') for (j=7;j>=0;j--) for (k=0;k<=7;k++) if ((peekb(0xf000,0xfa6e+j+8*txt[i]) & (0x80>>k))>0) {
  129.         limits(0,68+72*i+8*k-1,68+72*i+8*k+2,150+8*j-1,150+8*j+2,0,0,0,0,20,40,13,13,3,3,65);
  130.         create(0,&newpt);    for (l=1;l<=3000;l++);}
  131.     process(4,-1);}
  132.     gv=1;    for (j=1;(j<=800) && (num_active>0);j++) process(1,-1);
  133.     inr.x.ax=0x0003;    int86(0x10,&inr,&outr);    exit(0);} /*End terminate*/
  134. void calc_end() /*Calculate endpoint for burst*/
  135. {   endpt=NP-wait[ci]+1;    if ((mastercol=col[master[ci]])==15) mastercol=14;
  136.     alive[master[ci]]=-(endpt-(size[master[ci]]-1)*fade[master[ci]]);
  137.     xend=x[master[ci]]+endpt*xvel[master[ci]];
  138.     yend=y[master[ci]]+endpt*yvel[master[ci]]+(gv*endpt*endpt)/2;} /*End calc_end*/
  139. void startup(int devtype,int xi,int yi,int life,int p1,int p2,int p3,int p4,int waiting) /*Initializes a device*/
  140. {   ci=0;    while (item_alive[ci]>0) {process(1,waiting);    if (++ci>=NI) ci=0;}
  141.     devicetype[ci]=devtype;    item_alive[ci]=life;
  142.     switch(devicetype[ci]) {
  143.     /*SPURT*/ case 1:   coll[ci]=rnd(9,15);
  144.         limits(ci,xi-5,xi+5,340,340,3,8,-20,20,120,160,coll[ci],rnd(coll[ci],15),2,2,25);
  145.         wait[ci]=NP+130;    break;
  146.     /*FLARE*/ case 2:   coll[ci]=rnd(9,14);
  147.         limits(ci,xi-5,xi+5,340,340,4,8,-20,20,20,30,coll[ci],coll[ci]+1,2,2,2);
  148.         wait[ci]=50;    break;
  149.     /*BURST*/ case 3:   if (waiting<0) coll[ci]=rnd(9,14); else coll[ci]=mastercol;
  150.         limits(ci,xi-5,xi+5,yi-5,yi+5,rnd(p1,p2),rnd(p3,p4),-180,180,-2*burstlife,-burstlife,coll[ci],coll[ci]+1,2,2,rnd(burstlife,3*burstlife));
  151.         wait[ci]=NP;    break;
  152.     /*ROCKET*/ case 4:  limits(ci,xi,xi,340,340,5,10,p1,p2,-90,-80,9,15,3,4,3);
  153.         wait[ci]=20;    create(ci,&master[ci]);
  154.         limits(ci,xi,xi,340,340,-2,2,90,90,-6,-7,col[master[ci]],col[master[ci]],2,2,20);
  155.         vell[ci]=vell[ci]>>1;    velh[ci]=velh[ci]>>1;    calc_end();    break;
  156.     /*ROMAN*/ case 5:   limits(ci,xi,xi,340,340,6,11,-10,10,-70,-100,9,15,3,3,1);
  157.         wait[ci]=30;    create(ci,&master[ci]);    calc_end();
  158.     }   } /*End startup*/
  159. void multiple(int typ,int n,int rep,int life,int gap,int pause) /*Multiple item display*/
  160. {   int i,j;
  161.     for (j=1;j<=rep;j++) for (i=1;i<=n;i++) {
  162.         switch(typ) {
  163.         /*ROCKET*/ case 4: startup(rocket,320+100*rnd(-1,1),340,100,-45,45,0,0,-1);
  164.             if (rand()<25000) startup(burst,xend>>sh,yend>>sh,100,1,3,5,12,ci);    break;
  165.         /*ROMAN*/ case 5: startup(roman,i*(640/(n+1)),340,100,0,0,0,0,-1);
  166.             startup(burst,xend>>sh,yend>>sh,100,8,8,10,12,ci);    break;
  167.         default: if (typ==burst) startup(burst,rnd(150,540),rnd(50,200),life,1,3,5,12,-1);
  168.             else startup(typ,i*(640/(n+1)),340,life,0,0,0,0,-1);} /*End switch*/
  169.         process(gap,-1);}
  170.     process(pause,-1);}/*End multiple*/
  171. main(int argc,char **argv)
  172. {   inr.x.ax=0x0010;    int86(0x10,&inr,&outr);
  173.     inr.x.ax=0x1000;    inr.x.bx=0;    int86(0x10,&inr,&outr);
  174.     inr.x.ax=0x2c00;    int86(0x21,&inr,&outr);    srand(outr.x.dx);
  175.     setrange(&xmin,&xmax,5<<sh,634<<sh);    setrange(&ymin,&ymax,5<<sh,344<<sh);
  176.     for (im=0;im<NI;item_alive[im]=0,im++) /*Initialize items*/
  177.     for (jm=0;jm<TP;alive[jm]=0,next[jm]=jm+1,jm++); /*List of free points*/
  178.     freep=0;    next[sep-1]=-1; /*Restrict to first sep points mostly*/
  179.     for (im=0;im<=90;im++) {
  180.         sina[180+im]=sin(im/57.29578);     sina[180+-im]=-sina[180+im];
  181.         sina[180+180-im]=sina[180+im];     sina[180+im-180]=-sina[180+im];
  182.         cosa[180+im]=cos(im/57.29578);     cosa[180+-im]=cosa[180+im];
  183.         cosa[180+180-im]=-cosa[180+im];    cosa[180+im-180]=-cosa[180+im];}
  184.     do {multiple(flare,3,1,200,20,150);    multiple(spurt,1,1,450,20,500);
  185.         multiple(burst,5,1,100,10,75);     multiple(rocket,5,3,100,10,0);
  186.         multiple(burst,5,1,100,10,35);     multiple(spurt,2,1,450,20,500);
  187.         multiple(flare,4,1,200,20,150);    multiple(burst,5,1,100,10,25);
  188.         multiple(roman,5,3,100,10,60);
  189.         statev=-1;    burstlife=20; /*Set up for finale*/
  190.         startup(burst,150,200,100,1,3,3,5,-1);    process(30,-1);
  191.         startup(burst,500,100,100,1,3,3,5,-1);    process(50,-1);
  192.         startup(burst,250, 50,100,1,3,3,5,-1);    process(180,-1);
  193.         statev=0;    burstlife=10;    for (im=0;im<28000;im++) pokeb(0xa000,im,0);} /*End of finale*/
  194.     while ((argc>1) && ((argv[1][0]=='c') || (argv[1][0]=='C')));
  195.     terminate();
  196. } /*End main*/
  197.